package com.mpgame.database.redis.model;

import java.util.List;
import java.util.Map;
import java.util.Set;

import com.mpgame.database.redis.utils.RedisUtil;
import com.mpgame.utils.Log;

import io.lettuce.core.TransactionResult;

/**
 * Redis数据库上下文类
 */
public class RedisDBCtx {
    private final int dbIndex;
    
    public RedisDBCtx(int dbIndex) {
        this.dbIndex = dbIndex;
    }
    
    // String 操作
    public String set(String key, String value) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.set(key, value));
    }
    
    public String setex(String key, String value, long seconds) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.setex(key, seconds, value));
    }
    
    public String get(String key) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.get(key));
    }
    
    public Long del(String key) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.del(key));
    }
    
    public Boolean exists(String key) {
        Long res = RedisUtil.executeInDb(dbIndex, commands -> commands.exists(key));
        return res != null && res > 0;
    }
    
    public Boolean expire(String key, long seconds) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.expire(key, seconds));
    }
    
    public Long ttl(String key) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.ttl(key));
    }
    
    // Hash 操作
    public Boolean hset(String key, String field, String value) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.hset(key, field, value));
    }
    
    public String hget(String key, String field) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.hget(key, field));
    }
    
    public Map<String, String> hgetall(String key) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.hgetall(key));
    }
    
    public Long hdel(String key, String... fields) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.hdel(key, fields));
    }
    
    public Boolean hexists(String key, String field) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.hexists(key, field));
    }
    
    // Set 操作
    public Long sadd(String key, String... members) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.sadd(key, members));
    }
    
    public Long srem(String key, String... members) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.srem(key, members));
    }
    
    public Set<String> smembers(String key) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.smembers(key));
    }
    
    public Boolean sismember(String key, String member) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.sismember(key, member));
    }
    
    public Long scard(String key) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.scard(key));
    }
    
    // List 操作
    public Long lpush(String key, String... values) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.lpush(key, values));
    }
    
    public Long rpush(String key, String... values) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.rpush(key, values));
    }
    
    public String lpop(String key) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.lpop(key));
    }
    
    public String rpop(String key) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.rpop(key));
    }
    
    public List<String> lrange(String key, long start, long end) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.lrange(key, start, end));
    }
    
    public Long llen(String key) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.llen(key));
    }
    
    // 原子操作
    public Long incr(String key) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.incr(key));
    }
    
    public Long incrBy(String key, long increment) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.incrby(key, increment));
    }
    
    public Long decr(String key) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.decr(key));
    }
    
    public Long decrBy(String key, long decrement) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.decrby(key, decrement));
    }
    
    // 其他操作
    public List<String> keys(String pattern) {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.keys(pattern));
    }
    
    public String flushdb() {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.flushdb());
    }
    
    public String info() {
        return RedisUtil.executeInDb(dbIndex, commands -> commands.info());
    }
    
    // Pipeline 操作
    public TransactionResult pipeline(List<RedisCommand> commands) {
        return RedisUtil.executeInDb(dbIndex, redisCommands -> {
            redisCommands.multi();
            for (RedisCommand cmd : commands) {
                switch (cmd.getType()) {
                    case HGETALL:
                        redisCommands.hgetall(cmd.getKey());
                        break;
                    case SISMEMBER:
                        redisCommands.sismember(cmd.getKey(), cmd.getValue());
                        break;
                    case GET:
                        redisCommands.get(cmd.getKey());
                        break;
                    case SET:
                        redisCommands.set(cmd.getKey(), cmd.getValue());
                        break;
                    case SADD:
                        redisCommands.sadd(cmd.getKey(), cmd.getValue());
                        break;
                    case SREM:
                        redisCommands.srem(cmd.getKey(), cmd.getValue());
                        break;
                    default:
                        Log.warn("未支持的Redis命令类型：" + cmd.getType());
                        break;
                }
            }
            return redisCommands.exec();
        });
    }
}
